# -*- coding: utf-8 -*-
# !/usr/resources/python3

import time
from utils.Utility import Utility
from sqlalchemy import create_engine, func
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

# db connect
db_connect = Utility.config('db')


class Model:
    session = None

    def __init__(self):
        engine = create_engine(db_connect, echo=False)
        self.session = sessionmaker(bind=engine)()

    def insert(self, obj):
        self.session.add(obj)
        self.session.commit()

    def one(self, obj, filters, order=None):
        if order is None:
            return self.session.query(obj).filter(filters).first()
        else:
            return self.session.query(obj).filter(filters).order_by(order).first()

    def all(self, obj, filters):
        return self.session.query(obj).filter(filters).all()

    def all_order(self, obj, filters, order=None):
        return self.session.query(obj).filter(filters).order_by(order).all()

    def all_limit(self, obj, filters, limit=None):
        return self.session.query(obj).filter(filters).limit(limit).all()

    def all_limit_order(self, obj, filters, limit=None, order=None):
        return self.session.query(obj).filter(filters).order_by(order).limit(limit).all()

    def paging(self, obj, filters, page, size):
        page_number = self.page_number(obj, filters, size)
        # init
        page = int(page)
        size = int(size)
        # 判断页数是否合法
        if page < 1:
            page = 1
        if page > page_number:
            page = page_number
        # offset
        offset = size * (page - 1)
        # return
        return self.session.query(obj).filter(filters).offset(offset).limit(size).all()

    def count(self, obj, filters):
        return self.session.query(func.count(obj.id)).filter(filters).scalar()

    def page_number(self, obj, filters, size):
        count = self.count(obj, filters)
        page_number = Model.mod(count, size)
        if Model.rem(count, size) > 0:
            page_number = page_number + 1
        return page_number

    def update(self, obj):
        self.session.commit()

    def update_all(self):
        self.session.commit()

    def update_batch(self, obj, filters, data):
        self.session.query(obj).filter(filters).update(data, synchronize_session=False)
        self.session.commit()

    def save(self, obj):
        if obj.id is None:
            self.session.add(obj)
        self.session.commit()

    def delete(self, obj, filters):
        self.session.query(obj).filter(filters).delete()
        self.session.commit()

    def execute(self):
        return self.session

    def close(self):
        self.session.close()

    # 取模
    @staticmethod
    def mod(a, b):
        c = a % b
        r = int((a - c) / b)
        return r

    # 取余
    @staticmethod
    def rem(a, b):
        c = int(a / b)
        r = a - c * b
        return r

    def __del__(self):
        # self.session.close()
        pass
